library ieee ;
use ieee.std_logic_1164.all ;
use ieee.numeric_std.all ;

library lib_expoRNS ;

-- Unité de déoupage du nombre dans le système RNS
-- 


-------------------------------------

entity RNS_Dec_Unit is
generic(
	Z_RNS : positive range 1 to 256 ;		-- Nombre de bits du module
	
	N_alpha : positive ;	-- Vecteur de base : OBLIGATOIREMENT de la forme 2^n
	log2N_alpha :positive;
	
	N_beta1 : positive ;	-- Vecteur de base : OBLIGATOIREMENT PAS de la forme 2^n 
	R_beta1 : positive ;
	log2R_beta1 : positive ;
	k_beta1 : positive ;
	
	N_beta2 : positive ;	-- Vecteur de base : OBLIGATOIREMENT de la forme 2^n 
	R_beta2 : positive ;
	log2R_beta2 : positive ;
	k_beta2 : positive
) ;
port(
	a : in std_logic_vector(Z_RNS-1 downto 0) ;
	clk : in std_logic ;
	reset : in std_logic ;
	alpha : out std_logic_vector(Z_RNS-1 downto 0) ;
	beta1 : out std_logic_vector(Z_RNS-1 downto 0) ;
	beta2 : out std_logic_vector(Z_RNS-1 downto 0);
        start : out std_logic
) ;

end entity ;


--------------------------------------

architecture RDU of RNS_Dec_Unit is

component mod_Unit is
	generic(
		Z : positive range 1 to 256 ;
		N : positive 
	) ;
	port(
		clk	: in std_logic ;
		reset	: in std_logic ;
		s_in	: in std_logic_vector(Z-1 downto 0 ) ;
		
		s_out	: out std_logic_vector(Z-1 downto 0 ) ;
		b_fin	: out std_logic 
	) ;
end component ;

signal alpha_int : std_logic_vector( Z_RNS-1 downto 0 ) ;
signal beta1_in, beta2_in : std_logic_vector( 2*Z_RNS-1 downto 0 ) ;
signal beta1_out : std_logic_vector( 2*Z_RNS-1 downto 0 ) ;
signal beta2_out : std_logic_vector( 2*Z_RNS-1 downto 0 ) ;
signal temp1 : std_logic_vector (Z_RNS-1 downto log2N_alpha);
signal temp2 : std_logic_vector  (log2N_alpha-1 downto 0 );
signal fin1,fin2  : std_logic;



begin
	-- Pour le vecteur ALPHA
 -- alpha(Z_RNS-1 downto log2N_alpha) <= (others => '0');
 -- alpha(log2N_alpha-1 downto 0) <= a(log2N_alpha-1 downto 0);
	temp1 <= (others => '0');
	temp2 <= a(log2N_alpha-1 downto 0);
	alpha <= temp1 & temp2;
	
	-- Pour le vecteur BETA_1
	
	beta1_in <= std_logic_vector(unsigned(a) * R_beta1 );
	
	MOD1 : mod_Unit
	generic map( Z => 2*Z_RNS, N => N_beta1 ) 
	port map ( clk => clk, reset => reset, s_in => beta1_in, s_out => beta1_out, b_fin => fin1 ) ;
	
	beta1 <= std_logic_vector( resize( unsigned(beta1_out) , Z_RNS ) ) ;
	
	-- Pour le vecteur BETA_2
	
	beta2_in <= std_logic_vector(unsigned(a) * R_beta2 );
	
	MOD12: mod_Unit
	generic map( Z => 2*Z_RNS, N => N_beta2 ) 
	port map ( clk => clk, reset => reset, s_in => beta2_in, s_out => beta2_out, b_fin => fin2 ) ;
	
	beta2 <= std_logic_vector( resize( unsigned(beta2_out) , Z_RNS ) ) ;

        start <= (fin1 and fin2);
	
end RDU ;
